/*
STL 常用算法 查找算法
算法简介
  find  // 查找元素
  find_if  // 按条件查找
  adjacent_find  // 查找相邻重复元素
  binary_search  // 二分查找
  count  // 统计元素个数
  count_if  // 按条件统计

find
  查找指定元素，找到返回元素迭代器，找不到返回end()
  函数原型
    find(iterator beg, iterator end, value);  [beg, end), value要查找的元素

find_if
  按条件查找元素
  函数原型
    find_if(iterator beg, iterator end, _Pred);  [beg, end), _Perd 函数或者谓词(返回bool类型的仿函数)

adjacent_find
  查找相邻重复元素，返回相邻元素的第一个位置的迭代器
  函数原型
    adjacent_find(iterator beg, iterator end);

binary_search
  二分查找，查找指定元素是否存在，存在返回true， 负责false。容器中的元素要用自己先排序。
  函数原型
    binary_search(iterator beg, iterator end, value);

count
  统计元素个数
  函数原型
    count(iterator beg, iterator end, value);

count_if
  按条件统计元素个数
  函数原型
    count_if(iterator beg, iterator end, _Pred);  _Perd 函数或者谓词

*/

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;

// find
void test_find()
{
    cout << "-------------- find ---------------" << endl;
    vector<string> v = {"hi", "c++", "stl", "find"};
    auto it = find(v.begin(), v.end(), "stl");
    if (it != v.end())
        cout << "finded..." << endl;
    else
        cout << "not find..." << endl;
}

// find_if
class Person
{
public:
    Person(string name, int age) : m_name(name), m_age(age) {};

public:
    string m_name;
    int m_age;
};

// 谓词
class Greater50
{
public:
    bool operator()(const Person &p)
    {
        return p.m_age > 50;
    }
};

void test_find_if()
{
    cout << "-------------- find_if ---------------" << endl;
    Person p1 = {"alies", 50};
    Person p2 = {"jordan", 60};
    Person p3 = {"ieven", 50};
    Person p4 = {"alex", 40};
    Person p5 = {"linuse", 55};
    vector<Person> v = {p1, p2, p3, p4, p5};

    auto it = find_if(v.begin(), v.end(), Greater50());
    if (it != v.end())
        cout << "finded..." << endl;
    else
        cout << "not find..." << endl;
}

// adjacent_find
void test_adjacent_find()
{
    cout << "-------------- adjacent_find ---------------" << endl;
    vector<int> v = {1, 2, 5, 5, 2, 4, 4, 3};
    auto it = adjacent_find(v.begin(), v.end());
    if (it == v.end())
        cout << "not found..." << endl;
    else
        cout << "adjacent repaire element is: " << *it << endl;
}

// binary_search
void test_binary_search()
{
    cout << "-------------- binary_search ---------------" << endl;
    vector<int> v = {1, 2, 3, 4, 5, 6};
    bool res = binary_search(v.begin(), v.end(), 3);
    cout << "res: " << res << endl;
}

// count
void test_count()
{
    cout << "-------------- count ---------------" << endl;
    vector<int> v = {1, 2, 3, 2, 2, 3, 4, 2, 2, 3, 1, 4, 5, 6};
    int c = count(v.begin(), v.end(), 2);
    cout << c << endl;
}

// count_if
bool greater3(int val)
{
    return val > 3;
}

void test_count_if()
{
    cout << "-------------- count_if ---------------" << endl;
    vector<int> v = {1, 2, 3, 2, 2, 3, 4, 2, 2, 3, 1, 4, 5, 6};
    int c = count_if(v.begin(), v.end(), greater3);
    cout << c << endl;
}

int main()
{
    test_find();
    test_find_if();
    test_adjacent_find();
    test_binary_search();
    test_count();
    test_count_if();
}